﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;

namespace SensorDrone.Net
{
    /// <summary>
    /// An interface toa sensordrone
    /// </summary>
    public interface ISensorDrone : INotifyPropertyChanged,IDisposable
    {
        /// <summary>
        /// The drone Version
        /// </summary>
        string Version  { get; }
        /// <summary>
        /// The  drone MAC address
        /// </summary>
        string Address  { get; }
        /// <summary>
        /// The drone name
        /// </summary>
        string Name     { get; }
        /// <summary>
        /// Drone communication has be closed
        /// </summary>
        bool Cancelled  { get; }
        /// <summary>
        /// Drone is connected
        /// </summary>
        bool Connected  { get; }
        /// <summary>
        /// Lists the names of the registered sensors
        /// </summary>
        IEnumerable<ISensor> Sensors { get; }
        /// <summary>
        /// Notifies the status of a sensor
        /// </summary>
        event Action<string, bool>  Status;
        /// <summary>
        /// Notify a reading was taken
        /// </summary>
        event Action<Reading>       Reading;
        /// <summary>
        /// Notify an exception occured
        /// </summary>
        event Action<string>        Error;
        /// <summary>
        /// Connect to the drone asynchrounously
        /// <example>
        /// var connected = await drone.ConnectAsync();
        /// </example>
        /// </summary>
        /// <returns>True,if connected</returns>
        Task<bool>                  ConnectAsync();
        /// <summary>
        /// Enable all the sensors
        /// <example>
        /// var sensors = await drone.EnableAllAsync();
        /// </example>
        /// </summary>
        /// <returns>Names of all enabled sensors</returns>
        Task<IEnumerable<string>>   EnableAllAsync();
        /// <summary>
        /// Enable a sensor
        /// </summary>
        /// <param name="senor">The name of the sensor</param>
        /// <returns>True, if enabled</returns>
        bool                        Enable(string senor);
        /// <summary>
        /// Enable a sensor asynchrounously
        /// <example>
        /// var enable = await drone.EnableAsync("Ambient");
        /// </example>
        /// </summary>
        /// <param name="sensor">The sensor to enable</param>
        /// <returns>True, if enabled</returns>
        Task<bool>                  EnableAsync(string sensor);
        /// <summary>
        /// Disable a sensor
        /// </summary>
        /// <param name="sensor">The name of the sensor</param>
        /// <returns>True, if disabled</returns>
        bool                        Disable(string sensor);
        /// <summary>
        /// Sample a sensor
        /// </summary>
        /// <param name="sensor">The name of the sensor</param>
        /// <returns>A sensor reading</returns>
        Reading                     Sample(string sensor);
        /// <summary>
        /// Sample a sensor asynchronously
        /// <example>
        /// var reading = await drone.SampleAsync("Pressure");
        /// 
        /// </example>
        /// </summary>
        /// <param name="sensor">The name of the sensor</param>
        /// <returns>A sensor reading</returns>
        Task<Reading>               SampleAsync(string sensor);
        /// <summary>
        /// Register a new sensor on the drone
        /// <example>
        ///  drone.Register(new Sensor&lt;Humidity&gt;(Humidity.Relative, Enumerable.Empty&lt;Unit&lt;Humidity&gt;&gt;())
        ///    {
        ///        
        ///        Name = "Humidity",
        ///        Unit = "%",
        ///        Disable = channel => true,
        ///        Enable = channel => true,
        ///        Measure = channel => ReadHumidity(channel)
        ///    });
        /// </example>
        /// </summary>
        /// <param name="sensor">The sensor definition</param>
        void                        Register(ISensor sensor);
        /// <summary>
        /// Activate the LEDS asynchrounously
        /// </summary>
        /// <param name="color">The color to set</param>
        /// <returns>A Task to await for completion</returns>
        Task                        Leds(System.Windows.Media.Color color);
    }
}